package com.gaotai.wangfei.exam.ioc.parse;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.gaotai.wangfei.exam.ioc.config.Bean;
import com.gaotai.wangfei.exam.ioc.config.Property;
import com.gaotai.wangfei.exam.util.StringUtils;

/**
 * 
 * <p>
 * Description: [将xml数据组装成一个map对象，方便beanFactory创建相关的bean]
 * </p>
 * 
 * @author <a href="mailto: wangfei@gaotai.cn">王飞</a>
 * @version $Revision$
 */
public class ConfigManager
{

	/**
	 * 
	 * <p>
	 * 将xml转换为一个Map<bean名称,bean对象>
	 * </p>
	 * 
	 * @param path
	 *            配置的xml路径
	 * @return
	 * @author:wangfei 2016-3-18
	 * @update: [updatedate] [changer][change description]
	 */
	public static Map<String, Bean> getConfig(String path)
	{
		//需要返回的bean的名称以及bean的map
		Map<String, Bean> map = new HashMap<String, Bean>();
		if(StringUtils.isNullString(path))
		{
			return null;
		}
		//创建解析器
		SAXReader reader = new SAXReader();
		InputStream is = ConfigManager.class.getResourceAsStream(path);

		Document document = null;
		try
		{
			document = reader.read(is);
		}
		catch (DocumentException e)
		{
			e.printStackTrace();
			throw new RuntimeException("请检查xml配置是否正确!");
		}
		//定义xpath表达式
		String xpath = "//bean";
		//获得xml中所有的bean节点的list
		List<Element> beanElementList = document.selectNodes(xpath);

		//如果bean节点不为空则进行数据的组装工作
		if(beanElementList != null && !beanElementList.isEmpty())
		{
			for (Element beanEle : beanElementList)
			{
				Bean bean = new Bean();
				//获得bean节点下面 name与class的属性
				String name = beanEle.attributeValue("name");
				String className = beanEle.attributeValue("class");
				//获得bean借点下面的所有property节点
				List<Element> propertyElementList = beanEle.elements("property");
				List<Property> properties = new ArrayList<Property>();
				//遍历property中的所有的属性
				if(propertyElementList != null && !propertyElementList.isEmpty())
				{
					for (Element propertyEle : propertyElementList)
					{
						//赋值组装属性
						Property property = new Property();
						//property节点下所有value节点的文本值或者property中的value属性的值
						List<String> propertyValueList = new ArrayList<String>();
						//拦截器链
						List<String> propertyInterceptorList = new ArrayList<String>();
						//获得property中的name属性
						String propertyName = propertyEle.attributeValue("name");
						//获得property中的ref属性
						String propertyRef = propertyEle.attributeValue("ref");
						//直接获得property中的value下面的节点数据
						Element propertyValueEle = propertyEle.element("value");
						if(propertyValueEle != null)
						{
							propertyValueList.add(propertyValueEle.getText());
						}
						//获得property中的list节点
						Element propertyValueListEle = propertyEle.element("list");
						if(propertyValueListEle != null)
						{
							//获得list节点中的所有value节点的数据
							List<Element> propertyValueEleList = propertyValueListEle.elements("value");
							if(propertyValueEleList != null && !propertyValueEleList.isEmpty())
							{
								if(!propertyValueList.isEmpty())
								{
									throw new RuntimeException("property节点中不能既包含value属性，又包含value属性的List节点");
								}
								else
								{
									for (Element valueEle : propertyValueEleList)
									{
										propertyValueList.add(valueEle.getText());
									}
								}

							}
							//获得list节点中的interceptor节点的数据
							List<Element> propertyInterceptorEleList = propertyValueListEle.elements("interceptor");
							if(propertyInterceptorEleList != null && !propertyInterceptorEleList.isEmpty())
							{
								for (Element interceptorEle : propertyInterceptorEleList)
								{
									propertyInterceptorList.add(interceptorEle.getText());
								}
							}
						}
						//property属性赋值
						property.setName(propertyName);
						property.setValue(propertyValueList);
						property.setRef(propertyRef);
						property.setInterceptorList(propertyInterceptorList);
						//将property放入bean的properties
						properties.add(property);
					}
				}
				//bean属性赋值
				bean.setClassName(className);
				bean.setName(name);
				bean.setProperties(properties);
				//组装map
				map.put(name, bean);
			}
		}
		return map;
	}
}
